home *** CD-ROM | disk | FTP | other *** search
Text File | 1998-06-04 | 17.9 KB | 566 lines | [TEXT/MPS ] |
- #ifndef __ProcessServices__
- #include "ProcessServices.h"
- #endif __ProcessServices__
-
- #include <Processes.h> // for all Process Mgr related stuff
- #include <GestaltEqu.h> // for Gestalt call & check
- #include <ToolUtils.h> // for HiWord & LoWord calls
- #include <String.h> // for strcmp
- #include <StdLib.h> // for atol conversion string to num
- #include <SysEqu.h> // for ROMBase
-
- //—————————————————————————————————————————————————————————————————————————————————————
- // ProcessServices::ProcessServices - constructor.
- //—————————————————————————————————————————————————————————————————————————————————————
- ProcessServices::ProcessServices( char* pSrvname ):Service( pSrvname )
- {
- }
-
- //—————————————————————————————————————————————————————————————————————————————————————
- // ProcessServices::CheckForProcessMgr - make sure it's available before calling it
- //—————————————————————————————————————————————————————————————————————————————————————
- OSErr
- ProcessServices::CheckForProcessMgr()
- {
- OSErr result;
- long response;
-
- result = Gestalt( gestaltOSAttr, &response ); // Get Process Mgr attributes.
- if( result == noErr )
- {
- if( !(response & ( 1 << gestaltLaunchControl ))) // If proper attribute not set:
- {
- result = noProcessMgrErr; // change result from noErr to noProcessMgrErr.
- }
- }
- return result; // Returns noErr if Process Mgr is available.
- }
-
-
- //—————————————————————————————————————————————————————————————————————————————————————
- // ProcessServices::ProcessName2cstr - Convert Pascal str (with nulls!) to C str
- // (Desk accessory process names are Pascal strings that begin with a null: bad for C)
- //—————————————————————————————————————————————————————————————————————————————————————
- void
- ProcessServices::ProcessName2cstr( char* pProcessName )
- {
- short origLength;
- char* source;
- char* dest;
- short i;
- char theChar;
-
- origLength = pProcessName[0];
- source = &pProcessName[1]; // (Pascal string text starts at index 1)
- dest = pProcessName; // (C string text starts at index 0)
- for( i = 1; i <= origLength; i++ ) // Index through each char of Pascal string:
- {
- theChar = *source++; // Copy it only if it's non-null.
- if( theChar )
- {
- *dest++ = theChar;
- }
- }
- *dest = '\0'; // Terminate the C string with a zero.
- }
-
-
- //—————————————————————————————————————————————————————————————————————————————————————
- // ProcessServices::GetNamedProcessInfo - get information about given named app
- //—————————————————————————————————————————————————————————————————————————————————————
- OSErr
- ProcessServices::GetNamedProcessInfo( char* pDesiredProcessName, ProcessInfoRec* pInfoPtr )
- {
- ProcessSerialNumber thePSN;
- char aProcessName[32];
-
- pInfoPtr->processInfoLength = sizeof( ProcessInfoRec ); // Set up for GetProcessInfo call
- pInfoPtr->processName = ( StringPtr )aProcessName;
- pInfoPtr->processAppSpec = nil;
-
- thePSN.highLongOfPSN = 0;
- thePSN.lowLongOfPSN = kNoProcess;
- while( GetNextProcess( &thePSN ) == noErr ) // Iterate through processes:
- {
- if( GetProcessInformation( &thePSN, pInfoPtr ) == noErr )
- {
- ProcessName2cstr( aProcessName ); // (Convert pascal string with possible nulls)
- if( strcmp( aProcessName, pDesiredProcessName ) == 0 ) // if name matches:
- {
- return noErr; // info rec now contains info for named app.
- }
- }
- }
- return noSuchProcessErr; // No info rec with matching name found.
- }
-
-
- //—————————————————————————————————————————————————————————————————————————————————————
- // ProcessServices::ExtractAddr - Get long address from given parameter
- // (parameter can be a quoted longnumber 'number' or a regular Virtual User number )
- //—————————————————————————————————————————————————————————————————————————————————————
- OSErr
- ProcessServices::ExtractAddr(ScriptValue* pAddrItem, unsigned long* pAddrPtr)
- {
- ValueKind kind; // The kind of parameter passed
- char* numString; // If a string
-
- // Get what kind of parameter is passed in.
- kind = pAddrItem->GetValueKind();
-
- // If a number: just get it and return it.
- if( kind == kVUNumberKind )
- {
- *pAddrPtr = (( VUNumber* )pAddrItem)->GetNumber();
- return noErr;
- }
-
- // If a quoted string: expecting a quoted long number.
- if( kind == kVUStringKind )
- {
- // Get the string.
- numString = (( VUString* )pAddrItem )->GetText();
- // Convert the string to a returned long number.
- *pAddrPtr = atol( numString );
- return noErr;
- }
-
- // Else not a string or a list: return an error.
- return extractAddrErr;
- }
-
-
- //—————————————————————————————————————————————————————————————————————————————————————
- // ProcessServices::ValidateAddr - confirm address is RAM or ROM
- //—————————————————————————————————————————————————————————————————————————————————————
- OSErr
- ProcessServices::ValidateAddr( unsigned long pAddr )
- {
- OSErr result;
- long response;
- unsigned long ROMStart;
-
- // Check if address is in RAM:
- result = Gestalt( gestaltVMAttr, &response ); // Get VM status in response.
- if( result != noErr )
- {
- return result;
- }
-
- if( response & ( 1 << gestaltVMPresent )) // If VM active:
- {
- if( GetPageState(( void* )pAddr ) != kNotPaged )
- {
- return noErr; // Exit noErr if valid VM “RAM” address.
- }
- }
- else // Else VM not active:
- {
- result = Gestalt( gestaltPhysicalRAMSize, &response ); // Get RAM size in response.
- if( result != noErr )
- {
- return result;
- }
- if( pAddr < ( unsigned long )response )
- {
- return noErr; // Exit noErr if within RAM size.
- }
- }
-
- // If not exited yet, address is not in RAM: check if address is in ROM:
- ROMStart = *( unsigned long* )ROMBase; // Get base address of ROM.
- result = Gestalt( gestaltROMSize, &response ); // Get size of ROM in response.
- if(result != noErr )
- {
- return result;
- }
- if( pAddr >= ROMStart && pAddr < ROMStart + ( unsigned long )response )
- {
- return noErr; // Exit noErr if with ROM boundaries.
- }
- else
- {
- return validateAddrErr; // Else return invalid address error.
- }
- }
-
-
- //—————————————————————————————————————————————————————————————————————————————————————
- //—————————————————————————————————————————————————————————————————————————————————————
- // ProcessNamesListService::ProcessNamesListService - constructor
- //—————————————————————————————————————————————————————————————————————————————————————
- ProcessNamesListService::ProcessNamesListService():ProcessServices( "ProcessNamesList" )
- {
- }
-
- //—————————————————————————————————————————————————————————————————————————————————————
- // ProcessNameListService::ProcessRequest - get list of process names
- //—————————————————————————————————————————————————————————————————————————————————————
- OSErr
- ProcessNamesListService::ProcessRequest( Request* pReq )
- {
- OSErr result;
- VUList* namesList;
- ProcessInfoRec info;
- char aProcessName[32];
- ProcessSerialNumber thePSN;
-
- result = CheckForProcessMgr(); // Make sure Process Mgr is available.
- if( result != noErr )
- {
- pReq->SetErrorCode( result );
- pReq->SetErrorMessage( "ProcessTool: ProcessNamesList - Process Mgr not available on this Mac" );
- return result;
- }
-
- namesList = new VUList; // Make a list type for V.U.
-
- info.processInfoLength = sizeof( ProcessInfoRec );
- info.processName = ( StringPtr )aProcessName;
- info.processAppSpec = NULL;
-
- thePSN.highLongOfPSN = 0;
- thePSN.lowLongOfPSN = kNoProcess;
- while( GetNextProcess( &thePSN ) == noErr ) // Iterate through processes:
- {
- if( GetProcessInformation( &thePSN, &info ) == noErr )
- {
- ProcessName2cstr( aProcessName ); // Convert process name for V.U.
- namesList->PutNthItem( aProcessName ); // Add process name to list
-
- }
- }
- pReq->SetReturnValue( namesList ); // Return the list.
- return noErr;
- }
-
-
- //—————————————————————————————————————————————————————————————————————————————————————
- //—————————————————————————————————————————————————————————————————————————————————————
- // FrontProcessNameService::FrontProcessNameService - constructor
- //—————————————————————————————————————————————————————————————————————————————————————
- FrontProcessNameService::FrontProcessNameService():ProcessServices( "FrontProcessName" )
- {
- }
-
- //—————————————————————————————————————————————————————————————————————————————————————
- // FrontProcessNameService::ProcessRequest - get name of front process
- //—————————————————————————————————————————————————————————————————————————————————————
- OSErr
- FrontProcessNameService::ProcessRequest( Request* pReq )
- {
- OSErr result;
- ProcessSerialNumber thePSN;
- ProcessInfoRec info;
- char theProcessName[32];
-
- result = CheckForProcessMgr(); // Make sure Process Mgr is available.
- if( result != noErr )
- {
- pReq->SetErrorCode( result );
- pReq->SetErrorMessage( "ProcessTool: FrontProcessNameList - Process Mgr not available on this Mac" );
- return result;
- }
-
- result = GetFrontProcess( &thePSN ); // Get info about front process
- if( result != noErr )
- {
- pReq->SetErrorCode( result );
- pReq->SetErrorMessage( "ProcessTool: FrontProcessName - unable to get front process" );
- return result;
- }
-
- info.processInfoLength = sizeof( ProcessInfoRec );
- info.processName = ( StringPtr )&theProcessName;
- info.processAppSpec = nil;
- result = GetProcessInformation( &thePSN, &info );
- if( result != noErr )
- {
- pReq->SetErrorCode( result );
- pReq->SetErrorMessage( "ProcessTool: FrontProcessName - unable to get process's name" );
- return result;
- }
- ProcessName2cstr( theProcessName ); // Convert process name for V.U.
- pReq->SetReturnValue( theProcessName ); // Return process name.
- return noErr;
- }
-
-
- //—————————————————————————————————————————————————————————————————————————————————————
- //—————————————————————————————————————————————————————————————————————————————————————
- // PartitionSizeService::PartitionSizeService - constructor
- //—————————————————————————————————————————————————————————————————————————————————————
- PartitionSizeService::PartitionSizeService():ProcessServices( "PartitionSize" )
- {
- }
-
- //—————————————————————————————————————————————————————————————————————————————————————
- // PartitionSizeService::ProcessRequest - get partition size of front process
- //—————————————————————————————————————————————————————————————————————————————————————
- OSErr
- PartitionSizeService::ProcessRequest( Request* pReq )
- {
- OSErr result;
- ValueKind tItemKind;
- ScriptValue* tParam;
- char* theProcessName;
- ProcessInfoRec info;
-
- // Make sure Process Mgr is available.
- result = CheckForProcessMgr();
- if( result != noErr )
- {
- pReq->SetErrorCode( result );
- pReq->SetErrorMessage( "ProcessTool: PartitionSize - Process Mgr not available on this Mac" );
- return result;
- }
-
- // Make sure there is 1 parameter
- if( pReq->GetParamCount() != 1 )
- {
- pReq->SetErrorCode( paramErr );
- pReq->SetErrorMessage( "ProcessTool: PartitionSize - wrong number of parameters" );
- return paramErr;
- }
-
- // Read the parameter, specifying it to be a string.
- tItemKind = kVUStringKind;
- result = pReq->GetNthParam( 1, tParam, tItemKind );
- if( result != noErr )
- {
- pReq->SetErrorCode( result );
- pReq->SetErrorMessage( "ProcessTool: PartitionSize - failed to get process name parameter" );
- return result;
- }
- theProcessName = (( VUString* )tParam )->GetText();
-
- // Get the process information for that named application.
- result = GetNamedProcessInfo( theProcessName, &info );
- if( result != noErr )
- {
- pReq->SetErrorCode( result );
- pReq->SetErrorMessage( "ProcessTool: PartitionSize - unable to get process info" );
- return result;
- }
-
- // Return the partitionsize value from the process information.
- pReq->SetReturnValue(( long )info.processSize );
- return noErr;
- }
-
-
- //—————————————————————————————————————————————————————————————————————————————————————
- //—————————————————————————————————————————————————————————————————————————————————————
- // FreeMemService::FreeMemService - constructor
- //—————————————————————————————————————————————————————————————————————————————————————
- FreeMemService::FreeMemService():ProcessServices( "FreeMem" )
- {
- }
-
- //—————————————————————————————————————————————————————————————————————————————————————
- // FreeMemService::ProcessRequest - get free memory in front process's heap
- //—————————————————————————————————————————————————————————————————————————————————————
- OSErr
- FreeMemService::ProcessRequest( Request* pReq )
- {
- OSErr result;
- ValueKind tItemKind;
- ScriptValue* tParam;
- char* theProcessName;
- ProcessInfoRec info;
-
- // Make sure Process Mgr is available.
- result = CheckForProcessMgr();
- if( result != noErr )
- {
- pReq->SetErrorCode( result );
- pReq->SetErrorMessage( "ProcessTool: FreeMem - Process Mgr not available on this Mac" );
- return result;
- }
-
- // Make sure there is 1 parameter
- if( pReq->GetParamCount() != 1 )
- {
- pReq->SetErrorCode( paramErr );
- pReq->SetErrorMessage( "ProcessTool: FreeMem - wrong number of parameters" );
- return paramErr;
- }
-
- // Read the parameter, specifying it to be a string.
- tItemKind = kVUStringKind;
- result = pReq->GetNthParam( 1, tParam, tItemKind );
- if( result != noErr )
- {
- pReq->SetErrorCode( result );
- pReq->SetErrorMessage( "ProcessTool: FreeMem - failed to get process name parameter" );
- return result;
- }
- theProcessName = (( VUString* )tParam )->GetText();
-
- // Get the process information for that named application.
- result = GetNamedProcessInfo( theProcessName, &info );
- if( result != noErr )
- {
- pReq->SetErrorCode( result );
- pReq->SetErrorMessage( "ProcessTool: FreeMem - unable to get process info" );
- return result;
- }
-
- // Return the free memory value from the process information.
- pReq->SetReturnValue(( long )info.processFreeMem );
- return noErr;
- }
-
-
-
- //—————————————————————————————————————————————————————————————————————————————————————
- // ReadByteService::ReadByteService - constructor
- //—————————————————————————————————————————————————————————————————————————————————————
- ReadByteService::ReadByteService():ProcessServices( "ReadByte" )
- {
- }
-
- //—————————————————————————————————————————————————————————————————————————————————————
- // ReadByteService::ProcessRequest - read a byte from RAM or ROM
- //—————————————————————————————————————————————————————————————————————————————————————
- OSErr
- ReadByteService::ProcessRequest( Request* pReq )
- {
- ValueKind tItemKind;
- OSErr result;
- ScriptValue* tParam;
- unsigned long addr;
- short byteValue;
-
- // Make sure there is just one parameter.
- if( pReq->GetParamCount() != 1 )
- {
- pReq->SetErrorCode( paramErr );
- pReq->SetErrorMessage( "ProcessTool: ReadByte - wrong number of parameters" );
- return paramErr;
- }
-
- // Read the parameter. (It can be a number or longnumstring, so allow anything at first.)
- tItemKind = kVUAnyKind;
- result = pReq->GetNthParam( 1, tParam, tItemKind );
- if( result != noErr )
- {
- pReq->SetErrorCode( result );
- pReq->SetErrorMessage( "ProcessTool: ReadByte - failed to get address parameter" );
- return result;
- }
-
- // Convert the parameter (either form) to a long address of where to read bytes.
- result = ExtractAddr( tParam, &addr );
- if( result != noErr )
- {
- pReq->SetErrorCode( result );
- pReq->SetErrorMessage( "ProcessTool: ReadByte - bad address parameter" );
- return result;
- }
- result = ValidateAddr( addr );
- if( result != noErr )
- {
- pReq->SetErrorCode( result );
- pReq->SetErrorMessage( "ProcessTool: ReadByte - specified address is not in RAM or ROM" );
- return result;
- }
- byteValue = ( short )( *(( Byte* )addr ));
- pReq->SetReturnValue( byteValue );
- return noErr;
- }
-
-
- //—————————————————————————————————————————————————————————————————————————————————————
- // ReadBlockService::ReadBlockService - constructor
- //—————————————————————————————————————————————————————————————————————————————————————
- ReadBlockService::ReadBlockService():ProcessServices( "ReadBlock" )
- {
- }
-
- //—————————————————————————————————————————————————————————————————————————————————————
- // ReadBlockService::ProcessRequest - read a block of bytes from RAM or ROM
- //—————————————————————————————————————————————————————————————————————————————————————
- OSErr
- ReadBlockService::ProcessRequest( Request* pReq )
- {
- ValueKind tItemKind;
- OSErr result;
- ScriptValue* tParam;
- unsigned long addr;
- short lengthCount;
- VUList* readBlockList;
- short i;
-
- // Make sure there are 2 parameters
- if( pReq->GetParamCount() != 2 )
- {
- pReq->SetErrorCode( paramErr );
- pReq->SetErrorMessage( "ProcessTool: ReadBlock - wrong number of parameters" );
- return paramErr;
- }
-
- // Read the 1st parameter. (Can be a number or longnumstring, so allow anything at first.)
- tItemKind = kVUAnyKind;
- result = pReq->GetNthParam( 1, tParam, tItemKind );
- if( result != noErr )
- {
- pReq->SetErrorCode( result );
- pReq->SetErrorMessage( "ProcessTool: ReadBlock - failed to get address parameter" );
- return result;
- }
-
- // Convert the parameter (either form) to a long address of where to read a byte.
- result = ExtractAddr( tParam, &addr );
- if( result != noErr )
- {
- pReq->SetErrorCode( result );
- pReq->SetErrorMessage( "ProcessTool: ReadBlock - bad address parameter" );
- return result;
- }
-
- // Read the 2nd parameter, specifying it to be a number.
- tItemKind = kVUNumberKind;
- result = pReq->GetNthParam( 2, tParam, tItemKind );
- if(result != noErr )
- {
- pReq->SetErrorCode( result );
- pReq->SetErrorMessage( "ProcessTool: ReadBlock - failed to get count parameter" );
- return result;
- }
-
- // Get the number, the count of how many bytes to read back.
- lengthCount = (( VUNumber* )tParam )->GetNumber();
-
- // Make sure the starting address is in RAM or ROM.
- result = ValidateAddr( addr );
- if( result != noErr )
- {
- pReq->SetErrorCode( result );
- pReq->SetErrorMessage( "ProcessTool: ReadBlock - starting address is not in RAM or ROM" );
- return result;
- }
-
- // Make sure the ending address is in RAM or ROM.
- result = ValidateAddr( addr + lengthCount - 1 );
- if( result != noErr )
- {
- pReq->SetErrorCode( result );
- pReq->SetErrorMessage( "ProcessTool: ReadBlock - ending address is not in RAM or ROM" );
- return result;
- }
-
- // All clear! Read bytes from memory & add to end of a list.
- readBlockList = new VUList;
- for( i = 0; i < lengthCount; i++ )
- {
- readBlockList->PutNthItem(( short )(*( Byte* )( addr + i )));
- }
-
- // Return the list.
- pReq->SetReturnValue( readBlockList );
- return noErr;
- }
-
-
-